﻿#include "json.h"
#include <locale>
#include <codecvt>

#define SAFE_DELETE(p) \
    if ((p) != nullptr) \
    { \
        delete (p); \
        (p) = nullptr; \
    }

namespace SimpleJson
{

    /******************************class JsonReader**************************/

    JsonReader::JsonReader()
    {
        src_str = "";
        src_str_len = 0;
        curr_pos = -1;
        curr_line = 0;
        curr_col = 0;
        eof_flag = true;
    }

    JsonReader::JsonReader(const std::string& src_str_)
    {
        src_str = src_str_;
        src_str_len = src_str.size();
        if (src_str_len <= 0)
        {
            curr_pos = -1;
            curr_line = 0;
            curr_col = 0;
            eof_flag = true;
        }
        else
        {
            curr_pos = 0;
            curr_line = 1;
            curr_col = 1;
            eof_flag = false;
        }
    }

    JsonReader::JsonReader(std::ifstream& input_file_stream_)
    {
        if (!input_file_stream_)
        {
            throw JsonIOError("In JsonReader::JsonReader: _input_file_path is null!", 0, 0, false);
        }
        else
        {
            src_str = "";
            std::string line = "";
           
            // 逐行将 Json 文件内容读到字符串缓存中
            while (std::getline(input_file_stream_, line))
            {
                src_str += (line + '\n');
            }

            src_str_len = src_str.size();
            if (src_str_len <= 0)
            {
                curr_pos = -1;
                curr_line = 0;
                curr_col = 0;
                eof_flag = true;
            }
            else
            {
                curr_pos = 0;
                curr_line = 1;
                curr_col = 1;
                eof_flag = false;
            }
        }
    }

    JsonReader::~JsonReader()
    {
    }

    char JsonReader::currChar() const
    {
        return src_str[curr_pos];
    }

    char JsonReader::getChar()
    {
        if (eof_flag)
        {
            throw JsonIOError("Json file ends unexpectedly!",
                            getCurrLine(), getCurrCol());
        }

        // 根据当前字符更新行号和列号,并使文件游标 + 1
        char ch = src_str[curr_pos++];
        switch (ch)
        {
            case '\n':
            {
                curr_line++;
                curr_col = 1;
                break;
            }
            case '\t':
            {
                curr_col += 4;
                break;
            }
            case '\r':
            {
                curr_col = 1;
                break;
            }
            default:
            {
                curr_col++;
                break;
            }
        }

        if (curr_pos == src_str_len)
        {
            eof_flag = true;
        }

        return ch;
    }

    std::string JsonReader::strAhead(int n) const
    {
        return src_str.substr(curr_pos, std::min<int>(n, 
                              src_str_len - curr_pos));
    }

    std::string JsonReader::getStr(int n)
    {
        std::string str = strAhead(n);
        if (curr_pos >= src_str_len)
        {
            throw JsonIOError("Json file ends unexpectedly!",
                            getCurrLine(), getCurrCol());
        }
        curr_pos += n;
        return str;
    }

    int JsonReader::getCurrLine() const
    {
        return curr_line;
    }

    int JsonReader::getCurrCol() const
    {
        return curr_col;
    }

    void JsonReader::skip()
    {
        while (currChar() == ' '
            || currChar() == '\t'
            || currChar() == '\r'
            || currChar() == '\n')
        {
            getChar();
        }

        if (curr_pos == src_str_len)
        {
            eof_flag = true;
        }
    }

    bool JsonReader::isEOF() const
    {
        return eof_flag;
    }

    /******************************class Json*************************/

    Json::Json(JsonValueType value_type_/* = JSON_VALUE_TYPE_NULL*/)
    {
        setValueType(value_type_);
    }

    Json::Json(const Json& node)
    {
        value_type = node.value_type;

        switch (node.value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                value.value_int = node.value.value_int;
                break;
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                value.value_double = node.value.value_double;
                break;
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                value.value_bool = node.value.value_bool;
                break;
            }
            case JSON_VALUE_TYPE_STRING:
            {
                if (value.value_string == nullptr)
                {
#if defined(UNICODE)
                    value.value_string = new std::wstring(L"");
#elif defined(U16)
                    value.value_string = new std::u16string(u"");
#elif defined(U32)
                    value.value_string = new std::u32string(U"");
#else
                    value.value_string = new std::string("");
#endif
                    *(value.value_string) = *(node.value.value_string);
                }
                break;
            }
            case JSON_VALUE_TYPE_ARRAY:
            {
                if (value.value_array == nullptr)
                {
                    value.value_array = new ArrayValueType();
                    *(value.value_array) = *(node.value.value_array);
                }
                break;
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                if (value.value_obj == nullptr)
                {
                    value.value_obj = new ObjValueType();
                    *(value.value_obj) = *(node.value.value_obj);
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }

    Json::Json(int value)
    {
        setValueType(JSON_VALUE_TYPE_INT);
        setValue(value);
    }

    Json::Json(double value)
    {
        setValueType(JSON_VALUE_TYPE_DOUBLE);
        setValue(value);
    }

    Json::Json(bool value)
    {
        setValueType(JSON_VALUE_TYPE_BOOL);
        setValue(value);
    }

    Json::Json(const char* value)
    {
        setValueType(JSON_VALUE_TYPE_STRING);
        setValue(value);
    }

    Json::Json(const tstring& value)
    {
        setValueType(JSON_VALUE_TYPE_STRING);
        setValue(value);
    }

    Json::Json(const ObjValueType& value)
    {
        setValueType(JSON_VALUE_TYPE_OBJECT);
        setValue(value);
    }

    Json::Json(const ArrayValueType& value)
    {
        setValueType(JSON_VALUE_TYPE_ARRAY);
        setValue(value);
    }

    Json& Json::operator = (const Json& node)
    {
        if (&node == this)
        {
            return *this;
        }

        value_type = node.value_type;

        switch (node.value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                value.value_int = node.value.value_int;
                break;
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                value.value_double = node.value.value_double;
                break;
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                value.value_bool = node.value.value_bool;
                break;
            }
            case JSON_VALUE_TYPE_STRING:
            {
                SAFE_DELETE(value.value_string);
                if (value.value_string == nullptr)
                {
#if defined(UNICODE)
                    value.value_string = new std::wstring(L"");
#elif defined(U16)
                    value.value_string = new std::u16string(u"");
#elif defined(U32)
                    value.value_string = new std::u32string(U"");
#else
                    value.value_string = new std::string();
#endif
                    *(value.value_string) = *(node.value.value_string);
                }
                break;
            }
            case JSON_VALUE_TYPE_ARRAY:
            {
                SAFE_DELETE(value.value_array);
                if (value.value_array == nullptr)
                {
                    value.value_array = new ArrayValueType();
                    *(value.value_array) = *(node.value.value_array);
                }
                break;
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                SAFE_DELETE(value.value_obj);
                if (value.value_obj == nullptr)
                {
                    value.value_obj = new ObjValueType();
                    *(value.value_obj) = *(node.value.value_obj);
                }
                break;
            }
            default:
            {
                break;
            }
        }

        return *this;
    }

    Json::~Json()
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_STRING:
            {
                SAFE_DELETE(value.value_string);
                break;
            }
            case JSON_VALUE_TYPE_ARRAY:
            {
                value.value_array->clear();
                SAFE_DELETE(value.value_array);
                break;
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                value.value_obj->clear();
                SAFE_DELETE(value.value_obj);
                break;
            }
            default:
            {
                break;
            }
        }
    }

    JsonValueType Json::getValueType() const
    {
        return value_type;
    }

    int Json::getIntValue() const
    {
        if (value_type != JSON_VALUE_TYPE_INT)
        {
            throw JsonTypeError("In Json::getIntValue: value type mismatch!",
                "int", getValueTypeStr());
        }

        return value.value_int;
    }

    double Json::getDoubleValue() const
    {
        if (value_type != JSON_VALUE_TYPE_DOUBLE)
        {
            throw JsonTypeError("In Json::getDoubleValue: value type mismatch!",
                "double", getValueTypeStr());
        }
        
        return value.value_double;
    }

    bool Json::getBoolValue() const
    {
        if (value_type != JSON_VALUE_TYPE_BOOL)
        {
            throw JsonTypeError("In Json::getBoolValue: value type mismatch!",
                "bool", getValueTypeStr());
        }
        
        return value.value_bool;
    }

    const tstring& Json::getStringValue() const
    {
        if (value_type != JSON_VALUE_TYPE_STRING)
        {
            throw JsonTypeError("In Json::getStringValue: value type mismatch!",
                "string", getValueTypeStr());
        }
        
        if (value.value_string == nullptr)
        {
            throw JsonNullError("In Json::getStringValue: value_string is nullptr!");
        }

        return *(value.value_string);
        
    }

    const Json::ObjValueType& Json::getObjectValue() const
    {
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::getObjectValue: value type mismatch!",
                "object", getValueTypeStr());
        }

        if (value.value_obj == nullptr)
        {
            throw JsonNullError("In Json::getObjectValue: value_obj is nullptr!");
        }

        return *(value.value_obj);
    }

    const Json::ArrayValueType& Json::getArrayValue() const
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::getArrayValue: value type mismatch!",
                "array", getValueTypeStr());
        }

        if (value.value_array == nullptr)
        {
            throw JsonNullError("In Json::getArrayValue: value_array is nullptr!");
        }

        return *(value.value_array);
    }

    void Json::setValue(double value_)
    {
        if (value_type != JSON_VALUE_TYPE_DOUBLE)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "double", getValueTypeStr());
        }
        
        value.value_double = value_;
    }

    void Json::setValue(int value_)
    {
        if (value_type != JSON_VALUE_TYPE_INT)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "int", getValueTypeStr());
        }

        value.value_int = value_;
    }

    void Json::setValue(bool value_)
    {
        if (value_type != JSON_VALUE_TYPE_BOOL)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "bool", getValueTypeStr());
        }

        value.value_bool = value_;
    }

    void Json::setValue(const tstring& value_)
    {
        if (value_type != JSON_VALUE_TYPE_STRING)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "string", getValueTypeStr());
        }
        
        if (value.value_string == nullptr)
        {
            throw JsonNullError("In Json::setValue: value_string is nullptr!");
        }
        
        *(value.value_string) = value_;
    }

    void Json::setValue(const ObjValueType& value_)
    {
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "object", getValueTypeStr());
        }

        if (value.value_obj == nullptr)
        {
            throw JsonNullError("In Json::setValue: value_obj is nullptr!");
        }
        
        *(value.value_obj) = value_;
    }

    void Json::setValue(const ArrayValueType& value_)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::setValue: value type mismatch!",
                "array", getValueTypeStr());
        }

        if (value.value_array == nullptr)
        {
            throw JsonNullError("In Json::setValue: value_array is nullptr!");
        }

        *(value.value_array) = value_;
    }

    void Json::setValue(const char* value_)
    {
        setValue(toTString(std::string(value_)));
    }

    int Json::getChildrenSize() const
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY
            && value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::getChildrenSize: value type mismatch!",
                "(array, object)", getValueTypeStr());
        }
        else if (value_type == JSON_VALUE_TYPE_ARRAY)
        {
            if (value.value_array != nullptr)
            {
                return value.value_array->size();
            }
        }
        else
        {
            if (value.value_obj != nullptr)
            {
                return value.value_obj->size();
            }
        }

        return 0;
    }

    void Json::pushBack(const Json& node, const std::string& key/* = ""*/)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY &&
            value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::pushBack: value type mismatch!",
                "(array, object)", getValueTypeStr());
        }
        else
        {
            switch (value_type)
            {
                case JSON_VALUE_TYPE_ARRAY:
                {
                    if (value.value_array != nullptr)
                    {
                        value.value_array->push_back(node);
                    }
                    break;
                }
                case JSON_VALUE_TYPE_OBJECT:
                {
                    if (value.value_obj != nullptr)
                    {
                        value.value_obj->insert(std::make_pair(key, node));
                    }
                    break;
                }
                default:
                {
                    break;
                }
            }
        }   
    }

    void Json::pushFront(const Json& node)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::pushFront: value type mismatch!",
                "array", getValueTypeStr());
        }
        else
        {
            if (value.value_array != nullptr)
            {
                value.value_array->insert(value.value_array->begin(), node);
            }
        }   
    }

    void Json::clear()
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_ARRAY:
            {
                if (value.value_array != nullptr)
                {
                    value.value_array->clear();
                }
                break;
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                if (value.value_obj != nullptr)
                {
                    value.value_obj->clear();
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }

    bool Json::setArray(int size/* = 0*/)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_ARRAY);
        }
        
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            return false;
        }

        try
        {
            clear();
            for (int i = 0; i < size; i++)
            {
                Json new_element;
                pushBack(new_element);
            }
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            return false;
        }
        
        return true;
    }

    Json& Json::arrayGet(int index)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::arrayGet: value type mismatch!",
                "array", getValueTypeStr());
        }
        else
        {
            if (value.value_array == nullptr)
            {
                throw JsonNullError("In Json::arrayGet: value_array is nullptr!");
            }

            if (index >= (int)value.value_array->size() || index < 0)
            {
                throw JsonOutOfBoundError("In Json::arrayGet: array index out of bound!");
            }
            else
            {
                return ((*value.value_array)[index]);
            }
        }
    }

    void Json::arrayInsert(const Json& node, int index)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::arrayInsert: value type mismatch!",
                "array", getValueTypeStr());
        }
        else
        {
            if (value.value_array == nullptr)
            {
                throw JsonNullError("In Json::arrayInsert: value_array is nullptr!");
            }

            if (index > (int)value.value_array->size() || index < 0)
            {
                throw JsonOutOfBoundError("In Json::arrayInsert: array index out of bound!");
            }
            else
            {
                value.value_array->insert(value.value_array->begin() + index, node);
            }
        }
    }

    void Json::arrayErase(int index)
    {
        if (value_type != JSON_VALUE_TYPE_ARRAY)
        {
            throw JsonTypeError("In Json::arrayErase: value type mismatch!",
                "array", getValueTypeStr());
        }
        else
        {
            if (value.value_array == nullptr)
            {
                throw JsonNullError("In Json::arrayErase: value_array is nullptr!");
            }

            if (index >= (int)value.value_array->size() || index < 0)
            {
                throw JsonOutOfBoundError("In Json::arrayErase: array index out of bound!");
            }
            else
            {
                value.value_array->erase(value.value_array->begin() + index);
            }
        }
    }

    bool Json::objHasItem(const std::string& key)
    {
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::objHasItem: value type mismatch!",
                "object", getValueTypeStr());
        }
        else
        {
            if (value.value_obj == nullptr)
            {
                throw JsonNullError("In Json::objHasItem: value_obj is nullptr!");
            }

            return value.value_obj->find(key) != value.value_obj->end();
        }
    }
    
    Json& Json::objGetItem(const std::string& key)
    {
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("In Json::objGetItem: Value type mismatch!",
                "object", getValueTypeStr());
        }
        else
        {
            if (value.value_obj == nullptr)
            {
                throw JsonNullError("In Json::objGetItem: value_obj is nullptr!");
            }

            auto itFind = value.value_obj->find(key);
            if (itFind != value.value_obj->end())
            {
                return itFind->second;
            }
            else // 没找到
            {
                throw JsonNotFoundError("No item named: " + key);
            }
        }
    }

    void Json::objSetItem(const std::string& key, const Json& node)
    {
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("Value type mismatch!",
                "object", getValueTypeStr());
        }
        else
        {
            if (value.value_obj == nullptr)
            {
                throw JsonNullError("value.value_obj is nullptr!");
            }

            // 找到键名相同的子元素就替换之,没有找到就插入
            (*(value.value_obj))[key] = node;
        }
    }

    void Json::toJsonStr(std::string& dst_str_, 
                         bool print_key_/* = true*/,
                         int tab_num_/* = 0*/,
                         bool one_line_per_element_/* = false*/) const
    {
        dst_str_.clear();
        
        // 根据不同的值类型拼相应 Json 串
        switch (value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                std::string num_str = std::to_string(value.value_int);
                dst_str_ += num_str;
                break;
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                std::string num_str = std::to_string(value.value_double);
                dst_str_ += num_str;
                break;
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                value.value_bool ? dst_str_ += "true" : dst_str_ += "false";
                break;
            }
            case JSON_VALUE_TYPE_STRING:
            {
                if (value.value_string == nullptr)
                {
                    return;
                }
                dst_str_ += ('\"' + fromTString(*(value.value_string)) + '\"');
                break;
            }
            case JSON_VALUE_TYPE_ARRAY: // 数组,递归打印
            {
                if (value.value_array == nullptr)
                {
                    return;
                }
                dst_str_ += '[';
                
                for (size_t i = 0; i < value.value_array->size(); ++i)
                {
                    if (one_line_per_element_)
                    {
                        dst_str_ += '\n';
                        for (int i = 0; i < tab_num_ + 1; i++)
                        {
                            dst_str_ += '\t';
                        }
                        std::string element_str = "";
                        (*value.value_array)[i].toJsonStr(element_str,
                            false,
                            tab_num_ + 1,
                            true);
                        dst_str_ += element_str;
                    }
                    else
                    {
                        std::string element_str = "";
                        (*value.value_array)[i].toJsonStr(element_str,
                            false,
                            0,
                            false);
                        dst_str_ += element_str;
                    }

                    // 是否是最后一个元素
                    if (i != value.value_array->size() - 1)
                    {
                        dst_str_ += ',';
                    }
                    else
                    {
                        if (one_line_per_element_)
                        {
                            dst_str_ += '\n';
                            for (int i = 0; i < tab_num_; i++)
                            {
                                dst_str_ += '\t';
                            }
                            dst_str_ += ']';
                        }
                        else
                        {
                            dst_str_ += ']';
                        }
                        break;
                    }
                }
                
                if (value.value_array->empty())
                {
                    dst_str_ += ']';
                }
                break;
            }
            case JSON_VALUE_TYPE_OBJECT: // 对象,递归打印
            {
                if (value.value_obj == nullptr)
                {
                    return;
                }
                dst_str_ += '{';
                
                for (auto it = value.value_obj->begin(); it != value.value_obj->end(); ++it)
                {
                    if (one_line_per_element_)
                    {
                        dst_str_ += '\n';
                        for (int i = 0; i < tab_num_ + 1; i++)
                        {
                            dst_str_ += '\t';
                        }

                        if (print_key_)
                        {
                            dst_str_ += ('\"' + it->first + "\":");
                        }
                        std::string element_str = "";
                        it->second.toJsonStr(element_str,
                                        true, 
                                        tab_num_ + 1, 
                                        true);
                        dst_str_ += element_str;
                    }
                    else
                    {
                        if (print_key_)
                        {
                            dst_str_ += ('\"' + it->first + "\":");
                        }
                        std::string element_str = "";
                        it->second.toJsonStr(element_str,
                            true,
                            0,
                            false);
                        dst_str_ += element_str;
                    }

                    // 是否是最后一个元素
                    if (it != --value.value_obj->end())
                    {
                        dst_str_ += ',';
                    }
                    else
                    {
                        if (one_line_per_element_)
                        {
                            dst_str_ += '\n';
                            for (int i = 0; i < tab_num_; i++)
                            {
                                dst_str_ += '\t';
                            }
                            dst_str_ += '}';
                        }
                        else
                        {
                            dst_str_ += '}';
                        }
                        break;
                    }
                }
                
                if (value.value_obj->empty())
                {
                    dst_str_ += '}';
                }
                break;
            }
            case JSON_VALUE_TYPE_NULL:
            {
                dst_str_ += "NULL";
                break;
            }
            default:
            {
                break;
            }
        }
    }

    Json& Json::operator [] (const std::string& key)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_OBJECT);
        }
        
        if (value_type != JSON_VALUE_TYPE_OBJECT)
        {
            throw JsonTypeError("Value type mismatched!", "object", getValueTypeStr());
        }

        if (value.value_obj == nullptr)
        {
            throw JsonNullError("In Json::operator []: value_obj is nullptr!");
        }

        // 有此 key 就获取相应 value,没有就插入新元素
        auto itFind = value.value_obj->find(key);
        if (itFind != value.value_obj->end())
        {
            return itFind->second;
        }
        else
        {
            Json new_item;
            value.value_obj->insert(std::make_pair(key, new_item));
            return (*value.value_obj)[key];
        }
    }

    Json& Json::operator [] (int array_ind_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_ARRAY);
        }
        
        return arrayGet(array_ind_);
    }

    double Json::operator = (double value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_DOUBLE);
        }
        
        setValue(value_);
        return value_;
    }
    
    int Json::operator = (int value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_INT);
        }

        setValue(value_);
        return value_;
    }

    bool Json::operator = (bool value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_BOOL);
        }

        setValue(value_);
        return value_;
    }

    tstring Json::operator = (const tstring& value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_STRING);
        }

        setValue(value_);
        return value_;
    }

    tstring Json::operator = (const char* value_)
    {
        return operator=(toTString(std::string(value_)));
    }

    Json::ObjValueType Json::operator = (const ObjValueType& value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_OBJECT);
        }

        setValue(value_);
        return value_;
    }

    Json::ArrayValueType Json::operator = (const ArrayValueType& value_)
    {
        if (value_type == JSON_VALUE_TYPE_NULL)
        {
            setValueType(JSON_VALUE_TYPE_ARRAY);
        }

        setValue(value_);
        return value_;
    }

    int Json::asInt() const
    {
       switch (value_type)
       {
           case JSON_VALUE_TYPE_INT:
           {
               return value.value_int;
           }
           case JSON_VALUE_TYPE_DOUBLE:
           {
               return static_cast<int>(value.value_double);
           }
           case JSON_VALUE_TYPE_BOOL:
           {
               return static_cast<int>(value.value_bool);
           }
           case JSON_VALUE_TYPE_NULL:
           {
               return 0;
           }
           default:
           {
               throw JsonTypeError("Value is not convertible to Int!",
                   "(int, double, bool, null)", getValueTypeStr());
           }
       } 
    }

    double Json::asDouble() const
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                return static_cast<double>(value.value_int);
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                return value.value_double;
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                return static_cast<double>(value.value_bool);
            }
            case JSON_VALUE_TYPE_NULL:
            {
                return 0.0;
            }
            default:
            {
                throw JsonTypeError("Value is not convertible to Double!",
                    "(int, double, bool, null)", getValueTypeStr());
            }
       } 
    }

    bool Json::asBool() const
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                return static_cast<bool>(value.value_int);
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                return static_cast<bool>(value.value_double);
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                return value.value_bool;
            }
            case JSON_VALUE_TYPE_NULL:
            {
                return false;
            }
            default:
            {
                throw JsonTypeError("Value is not convertible to Bool!",
                    "(int, double, bool, null)", getValueTypeStr());
            }
        }
    }

    std::string Json::asString() const
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_STRING:
            {
                if (value.value_string == nullptr)
                {
                    return "";
                }
                
                return fromTString(*(value.value_string));
            }
            case JSON_VALUE_TYPE_INT:
            {
                return std::to_string(value.value_int);
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                return std::to_string(value.value_double);
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                return value.value_bool ? "true" : "false";
            }
            case JSON_VALUE_TYPE_NULL:
            {
                return "NULL";
            }
            default:
            {
                throw JsonTypeError("Value is not convertible to String!",
                    "(string, int, double, bool, null)", getValueTypeStr());
            }
        }
    }
 
    void Json::setValueType(JsonValueType value_type_)
    {
        value_type = value_type_;

        switch (value_type_)
        {
            case JSON_VALUE_TYPE_STRING:
            {
                if (value.value_string == nullptr)
                {
#if defined(UNICODE)
                    value.value_string = new std::wstring(L"");
#elif defined(U16)
                    value.value_string = new std::u16string("");
#elif defined(U32)
                    value.value_string = new std::u32string("");
#else
                    value.value_string = new std::string("");
#endif
                }
                break;
            }
            case JSON_VALUE_TYPE_ARRAY:
            {
                if (value.value_array == nullptr)
                {
                    value.value_array = new ArrayValueType();
                }
                break;
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                if (value.value_obj == nullptr)
                {
                    value.value_obj = new ObjValueType();
                }
                break;
            }
            default:
            {
                break;
            }
        }
    }

    std::string Json::getValueTypeStr(void) const
    {
        switch (value_type)
        {
            case JSON_VALUE_TYPE_INT:
            {
                return "int";
            }
            case JSON_VALUE_TYPE_DOUBLE:
            {
                return "double";
            }
            case JSON_VALUE_TYPE_BOOL:
            {
                return "bool";
            }
            case JSON_VALUE_TYPE_STRING:
            {
                return "string";
            }
            case JSON_VALUE_TYPE_ARRAY:
            {
                return "array";
            }
            case JSON_VALUE_TYPE_OBJECT:
            {
                return "object";
            }
            case JSON_VALUE_TYPE_NULL:
            {
                return "null";
            }
            default:
            {
                return "";
            }
        }
    }

    /******************************class JsonParser**************************/

    JsonParser::JsonParser()
    {
        success = false;
    }

    JsonParser::JsonParser(const std::string& json_str_)
    {
        try
        {
            JsonReader reader(json_str_);
            parseValue(root, reader);
            success = true;
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            success = false;
        }  
    }

    JsonParser::JsonParser(std::ifstream& ifs)
    {
        try
        {
            JsonReader reader(ifs);
            parseValue(root, reader);
            success = true;
        }
        catch(const std::exception& e)
        {
            std::cerr << e.what() << '\n';
            success = false;
        }  
    }

    JsonParser::~JsonParser()
    {        
    }

    Json& JsonParser::getRoot()
    {
        return root;
    }

    bool JsonParser::succeed() const
    {
        return success;
    }

    bool JsonParser::fail() const
    {
        return !success;
    }
    
    void JsonParser::parseValue(Json& node, JsonReader& reader)
    {
        reader.skip();

        // 根据当前字符进行解析
        char ch = reader.currChar();
        if (ch == '{') // 对象
        {
            parseObject(node, reader);
        }
        else if (ch == '\"') // 字符串
        {
            parseString(node, reader);
        }
        else if (ch == '[') // 数组
        {
            parseArray(node, reader);
        }
        else if (ch == '-' || isdigit(ch)) // 数字
        {
            parseNumber(node, reader);
        }
        else // false, true, NULL
        {
            if (reader.strAhead(5) == "false")
            {
                node.setValueType(JSON_VALUE_TYPE_BOOL);
                node.setValue(false);
                reader.getStr(5);
            }
            else if (reader.strAhead(4) == "true")
            {
                node.setValueType(JSON_VALUE_TYPE_BOOL);
                node.setValue(true);
                reader.getStr(4);
            }
            else if (reader.strAhead(4) == "NULL")
            {
                node.setValueType(JSON_VALUE_TYPE_NULL);
                reader.getStr(4);
            }
            else
            {
                throw JsonIOError("Invalid Symbol: " + ch, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
            }
        }
    }

    void JsonParser::parseNumber(Json& node, JsonReader& reader)
    {
        node.setValueType(JSON_VALUE_TYPE_DOUBLE);
        double sign = 1;
        int sub_scale = 0;
        double value = 0;
        int exp_sign = 1;
        int exp_val = 0;

        char curr_char = reader.currChar();
        if (curr_char != '-' && !isdigit(curr_char))
        {
            throw JsonIOError("Invalid Symbol: " + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
        }

        // 处理负号
        if (curr_char == '-')
        {
            sign = -1;
            reader.getChar();
            curr_char = reader.currChar();
        }
        
        if (isdigit(curr_char) && curr_char != '0')
        {
            while (isdigit(curr_char))
            {
                value = value * 10 + double(curr_char - '0');
                reader.getChar();
                curr_char = reader.currChar();
            }
        }
        else if (curr_char == '0') // 跳过前置 0
        {
            reader.getChar();
            curr_char = reader.currChar();
        }
        
        // 小数部分
        if (curr_char == '.')
        {
            reader.getChar();
            curr_char = reader.currChar();
            if (!isdigit(curr_char))
            {
                throw JsonIOError("Invalid Symbol: " + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
            }
            else
            {
                while (isdigit(curr_char))
                {
                    sub_scale++;
                    value = value + double(curr_char - '0') * 
                                    std::pow(0.1, double(sub_scale));
                    reader.getChar();
                    curr_char = reader.currChar();
                }
            }
        }

        // 幂部分
        if (curr_char == 'e' || curr_char == 'E')
        {
            reader.getChar();
            curr_char = reader.currChar();

            if (curr_char == '-')
            {
                exp_sign = -1;
                reader.getChar();
                curr_char = reader.currChar();
            }
            else if (curr_char == '+')
            {
                reader.getChar();
                curr_char = reader.currChar();
            }

            if (!isdigit(curr_char))
            {
                throw JsonIOError("Invalid Symbol:" + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
            }
            else
            {
                while (isdigit(curr_char))
                {
                    exp_val = exp_val * 10 + (curr_char - '0');
                    reader.getChar();
                    curr_char = reader.currChar();
                }
            }

            exp_val *= exp_sign;
        }

        value = (value * std::pow(10, double(exp_val))) * sign;
        node.setValue(value);

        // 整数
        if (sub_scale == 0)
        {
            node.setValueType(JSON_VALUE_TYPE_INT);
            node.setValue(int(value));
        }
    }

    void JsonParser::parseString(Json& node, JsonReader& reader)
    {
        node.setValueType(JSON_VALUE_TYPE_STRING);
        std::string str = "";

        char curr_char = reader.currChar();
        if (curr_char != '\"')
        {
            throw JsonIOError("Invalid string start symbol: " + curr_char,
                            reader.getCurrLine(), 
                            reader.getCurrCol());
        }
        else
        {
            reader.getChar();
            curr_char = reader.currChar();
        }

        while (curr_char != '\"')
        {
            if (curr_char == '\\') // 转义字符
            {
                reader.getChar();
                curr_char = reader.currChar();
                if (curr_char == '\"' || curr_char == '\\' || 
                    curr_char == '/' || curr_char == '\b' || 
                    curr_char == '\f' || curr_char == '\n' || 
                    curr_char == '\r' || curr_char =='\t')
                {
                    str += curr_char;
                }
                else if (curr_char == 'u') // unicode 字符 \uxxxx
                {
                    std::string unicode_str; 
                    for (int i = 0; i < 4; i++)
                    {
                        reader.getChar();
                        curr_char = reader.currChar();
                        if ((curr_char >= '0' && curr_char <= '9') || 
                            (curr_char >= 'a' && curr_char <= 'f') || 
                            (curr_char >= 'A' && curr_char <= 'F'))
                        {
                            unicode_str += curr_char;
                        }
                        else
                        {
                            throw JsonIOError("Invalid unicode string symbol: " + curr_char, 
                                            reader.getCurrLine(), 
                                            reader.getCurrCol());
                        }
                    }
                    
                    long unicode = strtol(unicode_str.data(), nullptr, 16);
                    std::string utf8_out = encode_utf8(unicode);
                    str += utf8_out;
                }
                else
                {
                    throw JsonIOError(std::string("Invalid escaped character: ") + '\\' + curr_char,
                                    reader.getCurrLine(), 
                                    reader.getCurrCol());
                }
                reader.getChar();
                curr_char = reader.currChar();
            }
            else // 非转义字符直接追加到结果字符串
            {
                str += curr_char;
                reader.getChar();
                curr_char = reader.currChar();
            }
        }

        reader.getChar(); // 跳过字符串结尾的 '\"'
        tstring strValue = toTString(str);
        node.setValue(strValue);
    }

    void JsonParser::parseArray(Json& node, JsonReader& reader)
    {
        node.setValueType(JSON_VALUE_TYPE_ARRAY);
        char curr_char = reader.currChar();
        if (curr_char != '[')
        {
            throw JsonIOError("Invalid string start symbol: " + curr_char, 
                            reader.getCurrLine(), 
                            reader.getCurrCol());
        }
        else
        {
            reader.getChar();
            reader.skip();
            curr_char = reader.currChar();
        }

        while (curr_char != ']')
        {
            // 创建数组元素
            Json element;
            parseValue(element, reader);
            node.pushBack(element);

            reader.skip();
            curr_char = reader.currChar();
            if (curr_char == ',')
            {
                reader.getChar();
                reader.skip();
            }
            else if (curr_char != ']') // 字符异常,Json 内容有误
            {
                throw JsonIOError("Invalid symbol: " + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
            }
            else // 当前字符为 ']',直接跳过并返回
            {
                reader.getChar();
                return;
            }
            curr_char = reader.currChar();
        }

        reader.getChar(); // 跳过数组结束符 ']'
    }

    void JsonParser::parseObject(Json& node, JsonReader& reader)
    {
        node.setValueType(JSON_VALUE_TYPE_OBJECT);
        char curr_char = reader.currChar();
        if (curr_char != '{')
        {
            throw JsonIOError("Invalid object start symbol: " + curr_char, 
                            reader.getCurrLine(), 
                            reader.getCurrCol());
        }
        else
        {
            reader.getChar();
            reader.skip();
            curr_char = reader.currChar();
        }

        // 逐个字符解析,直到对象范围结束
        while (curr_char != '}')
        {
            if (curr_char != '\"')
            {
                throw JsonIOError("Invalid symbol: " + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
            }
            else // 解析一个 k-v 对
            {
                reader.getChar();
                curr_char = reader.currChar();
                
                // 处理 key
                std::string key = "";
                while (curr_char != '\"')
                {
                    key += reader.getChar();
                    curr_char = reader.currChar();
                }
                reader.getChar();
                reader.skip();
                curr_char = reader.currChar();

                if (curr_char != ':')
                {
                    throw JsonIOError("Invalid symbol: " + curr_char, 
                                reader.getCurrLine(), 
                                reader.getCurrCol());
                }
                else // 处理 value
                {
                    reader.getChar();
                    reader.skip();
                    curr_char = reader.currChar();

                    // 创建对象的子元素
                    Json item;
                    parseValue(item, reader);
                    node.pushBack(item, key);

                    reader.skip();
                    curr_char = reader.currChar();

                    if (curr_char == ',')
                    {
                        reader.getChar();
                        reader.skip();
                    }
                    else if (curr_char != '}') // 字符异常,Json 内容有误
                    {
                        throw JsonIOError("Invalid symbol: " + curr_char,
                                        reader.getCurrLine(), 
                                        reader.getCurrCol());
                    }
                    else // 当前字符为 '}',直接跳过并返回
                    {
                        reader.getChar();
                        return;
                    }
                }
            }
            curr_char = reader.currChar();
        }

        reader.getChar();
    }

    void JsonParser::toString(std::string& output_str_, 
                              bool one_line_per_item_/* = false*/) const
    {
        output_str_.clear();
        root.toJsonStr(output_str_, true, 0, one_line_per_item_);
    }

    bool JsonParser::save(const std::string& output_file_path_, 
                          bool one_line_per_item_/* = false*/) const
    {
        std::ofstream ofs(output_file_path_);
        if (ofs.fail())
        {
            return false;
        }

        std::string output_str = "";
        toString(output_str, one_line_per_item_);
        ofs << output_str;
        ofs.close();

        return true;
    }

    /**************************工具函数****************************/

    std::string encode_utf8(long unicode)
    {
        std::wstring unicodeStr = L"";
        unicodeStr += (wchar_t)unicode;

        std::wstring_convert<std::codecvt_utf8<wchar_t>> strCnv;
        return strCnv.to_bytes(unicodeStr);
    }

    SimpleJson::tstring toTString(const std::string& str)
    {
#if defined(UNICODE)
        return std::wstring_convert< std::codecvt_utf8<wchar_t>, wchar_t >{}.from_bytes(str);
#elif defined(U16)
        return std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.from_bytes(str);
#elif defined(U32)
        return std::wstring_convert< std::codecvt_utf8<char32_t>, char32_t >{}.from_bytes(str);
#else
        return str;
#endif
    }

    std::string fromTString(const tstring& str)
    {
#if defined(UNICODE)
        return std::wstring_convert< std::codecvt_utf8<wchar_t>, wchar_t >{}.to_bytes(str);
#elif defined(U16)
        return std::wstring_convert< std::codecvt_utf8_utf16<char16_t>, char16_t >{}.to_bytes(str);
#elif defined(U32)
        return std::wstring_convert< std::codecvt_utf8<char32_t>, char32_t >{}.to_bytes(str);
#else
        return str;
#endif
    }

} // namespace SimpleJson
